package Year22_Month05.day29_2;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class TestReflect {
    public static void main1(String[] args) {
        //此时不能调用，就要通过反射处理
        //Student s = new Student("Peter","男",18);

        //获取字节码文件对象
        try {
            //1.通过class中的forName方法来进行获取
            Class<?> stuClassObj1 = Class.forName("Year22_Month05.day29_2.Student");
            //2. 使用.class方法，仅适合在编译器就已经明确要操作的Class
            Class<?> stuClassObj2 = Student.class;
            //3. 使用对象的getClass()方法,要先创建对象，但是对象是私有的，所以这里就有点矛盾，所以可以先把对象设置为公有的进行演示
            //Class<?> stuClassObj3 = s.getClass();
            System.out.println(stuClassObj1 == stuClassObj2);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {

        try {
            //1.获取Student类对象
            Class<?> stuClassObj = Class.forName("Year22_Month05.day29_2.Student");
            //2.获取Student类的构造方法
            Constructor<?> stuConstruct = stuClassObj.getDeclaredConstructor(String.class,String.class,int.class);
            //3.修改方法的访问权限
            stuConstruct.setAccessible(true);
            //4.调用该方法
            Student s = (Student) stuConstruct.newInstance("Peter","男",18);
            System.out.println(s);


            //反射私有的成员变量
            Field stuAge = stuClassObj.getDeclaredField("age");
            stuAge.setAccessible(true);
            stuAge.set(s,19);//因为有一个隐藏的this参数，所以这里前面要加一个this也就是s
            System.out.println(s);

            //反射私有的成员函数
            Method stuSetAge = stuClassObj.getDeclaredMethod("setAge", int.class);
            stuSetAge.setAccessible(true);
            stuSetAge.invoke(s,20);//调用setage这个方法
            System.out.println(s);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
